﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Net.Nntp.Cache
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;

    using Mews.Mime;

    /// <summary>Represents an outbound NNTP article.</summary>
    /// <threadsafety static="true" instance="false"/>
    public interface IOutboundArticle : IEquatable<IOutboundArticle>
    {
        /// <summary>Gets the host this article is associated with.</summary>
        IHost Host
        {
            get;
        }

        /// <summary>Gets the date of the article last passed to <see cref="SaveMessage"/>.</summary>
        /// <value>The body of the Date header field, if the article has one; otherwise <c>null</c>.</value>
        DateTime? DateUtc
        {
            get;
        }

        /// <summary>Gets the subject of the article last passed to <see cref="SaveMessage"/>.</summary>
        /// <value>The body of the Subject header field, if the article has one; otherwise <c>null</c>.</value>
        string Subject
        {
            get;
        }

        /// <summary>Gets or sets the send status of the article.</summary>
        /// <exception cref="ArgumentException">Attempted to set to <see cref="M:SendStatus.Sent"/>.</exception>
        /// <exception cref="InvalidOperationException">The message has already been sent; or,
        /// <see cref="Cache.IsSendReceiveInProgress"/> equals <c>true</c>.</exception>
        SendStatus SendStatus
        {
            get;
            set;
        }

        /// <summary>Gets or sets a value indicating whether the article has been deleted.</summary>
        /// <exception cref="InvalidOperationException"><see cref="Cache.IsSendReceiveInProgress"/> equals
        /// <c>true</c>.</exception>
        bool IsDeleted
        {
            get;
            set;
        }

        /// <summary>Loads the message from the database.</summary>
        /// <returns>A copy of the message previously passed to <see cref="SaveMessage"/>, if <see cref="SaveMessage"/>
        /// has been called successfully before; otherwise, a default-constructed <see cref="Message"/> object.
        /// </returns>
        Message LoadMessage();

        /// <summary>Saves <paramref name="message"/> to the database.</summary>
        /// <exception cref="ArgumentNullException"><paramref name="message"/> equals <c>null</c>.</exception>
        /// <exception cref="InvalidOperationException">The message has already been sent; or,
        /// <see cref="Cache.IsSendReceiveInProgress"/> equals <c>true</c>.</exception>
        /// <remarks>
        /// <para>Each call to this method performs the following steps:</para>
        /// <list type="number">
        /// <item>Compares <paramref name="message"/> to the one currently stored in the database. If it differs,
        /// then the <see cref="Entity.MessageId"/> property of <paramref name="message"/> is set to a new unique
        /// value.</item>
        /// <item>Sets the <see cref="Entity.Date"/> property of <paramref name="message"/> to the current date.</item>
        /// </list>
        /// </remarks>
        void SaveMessage(Message message);
    }
}
